package com.lemon.utils;

import com.lemon.entity.Computer;
import com.lemon.entity.Cpu;
import com.lemon.entity.Disk;
import com.lemon.entity.Memory;
import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;
import oshi.hardware.GlobalMemory;
import oshi.hardware.HardwareAbstractionLayer;
import oshi.software.os.FileSystem;
import oshi.software.os.OSFileStore;
import oshi.software.os.OperatingSystem;

import java.net.InetAddress;
import java.util.HashMap;
import java.util.Map;

import static com.lemon.constant.Constant.*;

public class GetHardwareDataUtil {

    private static GetHardwareDataUtil util = null;

    /**
     * 单例模式
     *
     * @return 单例
     */
    public static GetHardwareDataUtil getUtil() {
        if (util==null){
            synchronized (GetHardwareDataUtil.class) {
                if (util == null){
                    util = new GetHardwareDataUtil();
                }
            }
        }
        return util;
    }

    public Computer getComputer(){
        Computer result = new Computer();
        SystemInfo si = new SystemInfo();
        HardwareAbstractionLayer hal = si.getHardware();
        OperatingSystem os = si.getOperatingSystem();
        StringBuilder osName = new StringBuilder();
        osName.append(os.getManufacturer()).append(" ").append(os.getFamily())
                .append(" ").append(os.getVersion().getVersion());
        result.setOsName(osName.toString());
        result.setPcName(os.getNetworkParams().getHostName());
        result.setCpu(getCpu(hal.getProcessor()));
        result.setMemory(getMemory(hal.getMemory()));
        result.setDisk(getDisk(os.getFileSystem()));
        return result;
    }

    /**
     * 封装需要的cpu信息
     *
     * @return cpu信息
     */
    private Map<String, Cpu> getCpu(CentralProcessor processor){
        Map<String, Cpu> result = new HashMap<>();
        Cpu cpu = new Cpu();
        cpu.setModel(processor.getName());
        double num = processor.getSystemCpuLoad();
        cpu.setAvgUsageRate(((int) (num * 10000)));
        cpu.setLogicCoreNumber(processor.getLogicalProcessorCount());
        cpu.setPhysicCoreNumber(processor.getPhysicalProcessorCount());
        result.put(processor.getName(), cpu);
        return result;
    }

    /**
     * 封装需要的disk信息
     *
     * @return disk信息
     */
    private Map<String, Disk> getDisk(FileSystem fileSystem){
        Map<String, Disk> result = new HashMap<>();
        OSFileStore[] fsArray = fileSystem.getFileStores();
        for (OSFileStore fs : fsArray) {
            Disk disk = new Disk();
            result.put(fs.getMount(), disk);
            long usable = fs.getUsableSpace() / KB; // 可用
            long total = fs.getTotalSpace() / KB; // 总量
            disk.setDevName(fs.getMount());
            disk.setType(fs.getType());
            disk.setTotal(total + "");
            disk.setUse(total - usable + "");
        }
        return result;
    }

    /**
     * 封装需要的memory信息
     *
     * @return memory信息
     */
    private Memory getMemory(GlobalMemory memory) {
        Memory result = new Memory();
        long total = memory.getTotal() / KB;
        long available = memory.getAvailable() / KB;
        result.setTotal(total + "");
        result.setUse(total - available + "");
        return result;
    }
}
